/**
 * Copyright (c) 2008,中企动力华南研发中心
 * All rights reserved.
 */
package com.ce.pms.base.dao.impl;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.math.BigInteger;
//import java.sql.Statement;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.log4j.Logger;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.springframework.util.StringUtils;

import com.ce.common.util.BlankUtil;
import com.ce.pms.base.dao.IPmsBaseDao;
import com.ce.pms.base.dao.IPmsBaseHibernateDao;
import com.ce.pms.base.vo.SearchVO;
import com.ce.pms.common.dao.ISysrefcodeDao;
//import com.sitechasia.webx.core.exception.DataAccessLayerException;
import com.sitechasia.webx.core.model.IDomainObject;
import com.sitechasia.webx.core.support.Page;
import com.sitechasia.webx.core.utils.base.GenericsUtils;

/**
 * 功能描述:DAO的Hibernate实现类,继承Webx的HibernateDomainObjectDao类，但基本没用到它,提供泛型和分页

排序的支持
 *
 * <p>
 * 版权所有：中企动力
 * <p>
 * 未经本公司许可，不得以任何方式复制或使用本程序任何部分
 *
 * @author <a href="malto:wuqiaoyun@myce.net.cn">伍巧云</a>
 * Created on 2008-4-9
 *
 * @version $LastChangedRevision$ $LastChangedBy$ $LastChangedDate$
 *
 */
public class PmsBaseDaoImpl<D extends IDomainObject> implements IPmsBaseDao<D> {



	/*
	 * (non-Javadoc)
	 * @see com.ce.pms.base.dao.IPmsBaseDao#getLogger()
	 */
	public Logger getLogger() {
		return Logger.getLogger(getClass());
	}

	/**
	 * 获取任一页第一条数据在数据集的位置.
	 *
	 * @param currentPage
	 *            从1开始的当前页号
	 * @param pageSize
	 *            每页记录条数
	 * @return 该页第一条数据号
	 */
	protected static int getFirstRow(int currentPage, int pageSize) {
		return Page.getStartOfPage(currentPage, pageSize);
	}
	private static String buildCountQueryHQLStr(String queryStr) {
		int index = removeOrders(queryStr).toLowerCase().indexOf("from");
		StringBuilder builder = new StringBuilder("select count(*) ");
//		StringBuilder builder = new StringBuilder("select count(*) from ( ");
//		builder.append(removeOrders(queryStr)).append(" ) temp");
//		return builder.toString();

		if (index != 0) {
			builder.append(queryStr.substring(index));
		} else {
			builder.append(queryStr);
		}
		return builder.toString();
	}
	/**
	 * 构造一个查询数据条数的语句,不能用于union
	 *
	 * @param queryStr
	 *            源语句
	 * @return 查询数据条数的语句
	 * Edit author:罗军林
	 * Edit on:2008-6-16
	 * Why:修正了select 语句当有DISTINCT关键字时，记录总数不对的BUG
	 */
	private static String buildCountQueryStr(String queryStr) {
//		int index = removeOrders(queryStr).toLowerCase().indexOf("from");
//		StringBuilder builder = new StringBuilder("select count(*) ");
		StringBuilder builder = new StringBuilder("select count(*) from ( ");
		builder.append(removeOrders(queryStr)).append(" ) temp");
		return builder.toString();

//		if (index != 0) {
//			builder.append(queryStr.substring(index));
//		} else {
//			builder.append(queryStr);
//		}
//		return builder.toString();
	}
	/**
	 * 去除查询语句的orderby 子句
	 *
	 */
	private static String removeOrders(String queryStr) {
		Matcher m = Pattern.compile("order\\s*by[\\w|\\W|\\s|\\S]*",
				Pattern.CASE_INSENSITIVE).matcher(queryStr);
		StringBuffer sb = new StringBuffer();
		while (m.find()) {
			m.appendReplacement(sb, "");
		}
		m.appendTail(sb);
		return sb.toString();
	}

	protected ISysrefcodeDao sysrefcodeDao;

	private Class entityClass = GenericsUtils.getGenericClass(this.getClass());

	private IPmsBaseHibernateDao pmsBaseHibernateDao;

	/**
	 * 功能描述: 返回带命名参数的查询Query
	 * @param queryStr  查询语句
	 * @param parameter 命名参数的键值
	 * @return Query
	 * Create author:
	 * Create on:
	 * Edit author:罗军林
	 * Edit on:2008-8-7
	 * Why:方便数据拦截
	 */
	public Query createNameQuery(String queryStr, Map parameter) {
		Query query = this.pmsBaseHibernateDao.createQuery(queryStr);
		query.setProperties(parameter);
		return query;
	}

	/**
	 * 功能描述: 返回查询的Query
	 * @param queryStr  查询语句
	 * @param values    查询条件
	 * @return Query
	 * Create author:
	 * Create on:
	 * Edit author:燕大为
	 * Edit on:2008-5-21
	 * Why:方便数据拦截
	 */
	public Query createQuery(String queryStr, Object... values) {
		Query query = this.pmsBaseHibernateDao.createQuery(queryStr);
		if (values != null) {
			for (int i = 0; i < values.length; i++) {
				query.setParameter(i, values[i]);
			}
		}
		return query;
	}

	/** 原生sql查询
	 * @param queryStr
	 * @param values
	 * @return
	 */
	public Query createSQLQuery(String queryStr, Object... values) {
		Query query = this.pmsBaseHibernateDao.createSQLQuery(queryStr);
		if (values != null) {
			for (int i = 0; i < values.length; i++) {
				query.setParameter(i, values[i]);
			}
		}
		return query;
	}

	/**
	 * 功能描述:原生SQL的命名参数查询<br>
	 * @param queryStr
	 * @param parameter
	 * @return<br>
	 * Create author:罗军林<br>
	 * Create on:2008-12-23<br>
	 * Edit author:<br>
	 * Edit on:<br>
	 * Why:<br>
	 */
	public Query createNameSQLQuery(String queryStr, Map parameter) {
		Query query = this.pmsBaseHibernateDao.createSQLQuery(queryStr);
		query.setProperties(parameter);
		return query;
	}

	/**
	 * 功能描述:根据给定根据条件(支持模糊查询)组装一个Criteria对象
	 * @param String name
	 * @param Object value
	 * @return Criteria
	 * Create author:燕大为
	 * Create on:2008-5-21
	 * Edit author:
	 * Edit on:
	 * Why:
	 */
	public Criteria criteriaFindByLike(String name, String value) {
		return this.pmsBaseHibernateDao.createCriteriaByLike(this.entityClass, name, value);
	}

	/**
	 * 功能描述:根据给定根据条件(唯一查询)组装一个Criteria对象
	 * @param String name
	 * @param Object value
	 * @return Criteria
	 * Create author:燕大为
	 * Create on:2008-5-21
	 * Edit author:
	 * Edit on:
	 * Why:
	 */
	public Criteria criteriaFindUniqueBy(String name, Object value) {
		return this.pmsBaseHibernateDao.createCriteriaUniqueBy(this.entityClass, name, value);
	}

    /**
	 * 功能描述:根据给定根据条件组装一个Criteria对象
	 * @param String name
	 * @param Object value
	 * @return Criteria
	 * Create author:燕大为
	 * Create on:2008-5-21
	 * Edit author:
	 * Edit on:
	 * Why:
	 */
	public Criteria crtieriaFindBy(String name, Object value) {
		return this.pmsBaseHibernateDao.createCriteriaBy(this.entityClass, name, value);
	}

    /**
	 * Function:删除实体
	 * @param o 实体对象
	 * Create author:daibiao
	 * Create on:2008-1-28
	 * Edit author:
	 * Edit on:
	 * Why:
	 */
    public void deleteObject(D o) {
//	try {
    		this.doDelete(o);
//  	} catch (DataAccessException e) {
//    	throw new DataAccessLayerException("pms.base.001");
//	}
    }
    /**
	 * Function:根据Id删除实体
	 * @param 序列化值
	 * Create author:daibiao
	 * Create on:2008-1-28
	 * Edit author:
	 * Edit on:
	 * Why:
	 */
    public void deleteObjectById(Serializable id) {
//        try {
//        	super.doDeleteById(id);
    		this.doDeleteById(id);
//        } catch (DataAccessException e) {
//        	throw new DataAccessLayerException("pms.base.001");
//		}
    }

    /**
	 * Function:根据Ids数组批量删除实体
	 * @param 序列化参数列表
	 * Create author:daibiao
	 * Create on:2008-1-28
	 * Edit author:
	 * Edit on:
	 * Why:
	 */
    public void deleteObjectByIds(Serializable ids[]) {
//   try {
//       	super.doDeleteByIds(ids);
    		this.doDeleteByIds(ids);
//       } catch (DataAccessException e) {
//      	throw new DataAccessLayerException("pms.base.001");
//		}
    }

	/**
	 * 建议使用deleteObject方法
	 */
	@Deprecated
	public void doDelete(D o) {
		this.pmsBaseHibernateDao.genericRemove(o.getClass(), o);
	}

	/**
	 * 建议使用deleteObjectById方法
	 */
	@Deprecated
	public void doDeleteById(Serializable id) {
		this.pmsBaseHibernateDao.genericRemoveById(this.entityClass, id);
	}

	/**
	 * 建议使用deleteObjectByIds方法
	 */
	@Deprecated
	public void doDeleteByIds(Serializable[] ids) {
		for(Serializable id : ids) {
			this.pmsBaseHibernateDao.genericRemoveById(this.entityClass, id);
		}
	}




	/**
	 * 建议使用 saveObject方法
	 */
	@Deprecated
	public void doSave(D o) {

		this.pmsBaseHibernateDao.genericSave(o.getClass(), o);

	}

	/**
	 * Function:添加实体集合
	 * @param
	 * @return
	 * Create author:daibiao
	 * Create on:2008-1-28
	 * Edit author:燕大为
	 * Edit on: 2008-5-21
	 * Why: 方便数据拦截
	 */
	public void doSaveAll(Collection<D> list) {

		this.pmsBaseHibernateDao.genericSaveAll(this.entityClass, list);

	}

	/**
	 * Function:执行原生sql
	 * @param sql
	 * @param args  注入的参数数组
	 * @return
	 * Create author:yuguogang
	 * Create on:2008-3-24
	 * Edit author:
	 * Edit on:
	 * Why:
	 * @throws Exception
	 */
	public void executeSQL(final String sql,final Object[] args) {

		this.pmsBaseHibernateDao.executeSQL(sql, args);

	}

	/**
	 * Function:执行原生sql
	 * @param sql
	 * @param args  注入的二维参数数组
	 * @return
	 * Create author:yuguogang
	 * Create on:2008-3-24
	 * Edit author:
	 * Edit on:
	 * Why:
	 * @throws Exception
	 */
	public void executeSQL(final String sql,final Object[][] args) {
		this.pmsBaseHibernateDao.executeSQL(sql, args);
	}

	/**
	 * 功能描述:  加载列出所有实体
	 * @return DO对象列表
	 * Edit author:燕大为
	 * Edit on: 2008-5-21
	 * Why: 方便数据拦截
	 * Why: load方法有懒加载问题,涉及数据权限查询禁止使用,
	 * 请采用其他方法以hsql方式查询以便拦截,最好避免使用
	 */
    public List<D> findAll() {
//    	try {
//    	return super.findAll();
    	return this.pmsBaseHibernateDao.genericGetAll(this.entityClass);
//    	} catch (DataAccessException e) {
//			throw new DataAccessLayerException("pms.base.001");
//		}
    }

	/**
	 * 功能描述： 返回查询语句范围内的所有数据的数组
	 *
	 * @param queryStr: 查询语句
	 * @param paremeters
	 */
	public List findAllResult(String queryStr, Object... paramenters) {
		return this.createQuery(queryStr, paramenters).list();
	}

	/**
	 * Function:根据属性名称及值查询实体列表
	 * @param name 查询条件名
	 * @param value 查询条件值
	 * @return 查询结果列表
	 * Create author:daibiao
	 * Create on:2008-1-28
	 * Edit author: 付湘辉
	 * Edit on: 2008-05-12
	 * Why: 此方法因数据权限拦截问题禁止使用,改为使用criteriaFindByLike,
	 * criteriaFindUniqueBy,crtieriaFindBy获取Criteria对象,再调用findUnique或queryObjects
	 */
    @Deprecated
    public List<D> findBy(String name, Object value) {
//   try {
//        	return super.findBy(name, value);
    		return  this.queryObjects(this.criteriaFindUniqueBy(name, value));
//      } catch (DataAccessException e) {
//     	throw new DataAccessLayerException("pms.base.001");
//		}
    }

	/**
	 * Function:根据Id查询实体
	 * @param  序列化值
	 * @return DO对象
	 * Create author:daibiao
	 * Create on:2008-1-28
	 * Edit author:燕大为
	 * Edit on: 2008-5-21
	 * Why: 方便数据拦截
	 */
    public D findById(Serializable id) {
//    	try {
//    		return super.findById(id);
    		return (D)this.pmsBaseHibernateDao.genericGet(this.entityClass, id);
//    	} catch (DataAccessException e) {
//			throw new DataAccessLayerException("pms.base.001");
//		}
    }

	/**
	 * Function:根据属性名称及值模糊查询实体列表
	 * @param name 查询条件名
	 * @param value 查询条件值
	 * Create author:daibiao
	 * Create on:2008-1-28
	 * Edit author:
	 * Edit on:
	 * Why: 此方法因数据权限拦截问题禁止使用,改为使用criteriaFindByLike,
	 * criteriaFindUniqueBy,crtieriaFindBy获取Criteria对象,再调用findUnique或queryObjects
	 */
    @Deprecated
    public List<D> findByLike(String name, String value) {
//   try {
//    	return super.findByLike(name, value);
    	return this.queryObjects(this.criteriaFindByLike(name, value));
// 	} catch (DataAccessException e) {
//    	throw new DataAccessLayerException("pms.base.001");
//	}
    }

    /**
	 * Function:根据给定 Criteria 查询单个实体
	 * @param Criteria
	 * @return Object
	 * Create author:付湘辉
	 * Create on:2008-5-12
	 * Edit author:燕大为
	 * Edit on:2008-5-21
	 * Why:
	 */
	public Object findUnique(Criteria criteria) {
		return this.pmsBaseHibernateDao.queryUnique(criteria);
	}

	/**
	 * Function:根据属性名称及值查询唯一实体
	 * @param name 查询条件名
	 * @param value 查询条件值
	 * Create author:daibiao
	 * Create on:2008-1-28
	 * Edit author:
	 * Edit on:
	 * Why: 此方法因数据权限拦截问题禁止使用,改为使用criteriaFindByLike,
	 * criteriaFindUniqueBy,crtieriaFindBy获取Criteria对象,再调用findUnique或queryObjects
	 */
    @Deprecated
    public D findUniqueBy(String name, Object value) {
		// try {
		// 		return super.findUniqueBy(name, value);
		return (D) this.findUnique(this.criteriaFindUniqueBy(name, value));
		// } catch (DataAccessException e) {
		// 		throw new DataAccessLayerException("pms.base.001");
		// }
    }

	/**
	 * Function:查询数据库系统的时间
	 * Create author:yuguogang
	 * Create on:2008-3-13
	 * Edit author:燕大为
	 * Edit on:2008-5-21
	 * Why:
	 */
	public Date getDate() {
		SQLQuery q = this.pmsBaseHibernateDao.createSQLQuery("SELECT CURRENT_TIMESTAMP");
		return (Date) q.uniqueResult();
	}

	/**
	 * 功能描述:根据给定根据条件判断是否唯一
	 * @param D domainObject
	 * @param String names 如 查询name=davide,age=12
	 * @return boolean
	 * Create author:燕大为
	 * Create on:2008-5-21
	 * Edit author:
	 * Edit on:
	 * Why:
	 */
	public boolean isNotUnique(D domainObject, String names) {
		return this.pmsBaseHibernateDao.isGenericNotUnique(this.entityClass, domainObject, names);
	}

	/**
	 * 功能描述: 分页查询，支持HQL语句命名参数的查询
	 * @param hql: 查询语句
	 * @param currentPage : 当前页码
	 * @param pagesize： 每页的记录数
	 * @param parameters ： 命名参数的键值
	 * Edit author: 罗军林
	 * Edit on: 2008-8-12
	 *
	 * @return 分页对象
	 */
	public Page pagedNameQueryByPageNo(String hql,
									   int currentPage,
									   int pageSize,
									   Map parameter) {
	    long totalCount = this.getTotalCount(hql,parameter,true);  //获取总行数
	    if (totalCount < 1) {
	    	return new Page();
	    }

		int startIndex = getFirstRow(currentPage, pageSize);//获取开始行

		// 构建page对象
		return new Page(startIndex,
						totalCount,
						pageSize,
						this.queryNamePagedResult(hql,startIndex,pageSize,parameter));
	}

	/**
	 * 功能描述: 无查询条件的分页查询
	 * @param hql: 查询语句
	 * @param currentPage : 当前页码
	 * @param pagesize： 每页的记录数
	 *
	 * @return 分页对象
	 */
	public Page pagedQueryByPageNo(String hql, int pageNo, int pageSize) {
		return this.pagedQueryByPageNo(hql, pageNo, pageSize, null);
	}


	/**
	 * 功能描述: 分页查询
	 * @param hql: 查询语句
	 * @param currentPage : 当前页码
	 * @param pagesize： 每页的记录数
	 * @param parameters ： 查询条件参数
	 *
	 * @return 分页对象
	 */
	public Page pagedQueryByPageNo(String hql, int currentPage, int pageSize,
			Object[] parameters) {
		long totalCount = this.getTotalCount(hql, parameters, true); // 获取总行数
		if (totalCount < 1) {
			return new Page();
		}
		int startIndex = getFirstRow(currentPage, pageSize);// 获取开始行
		// 构建page对象
		return new Page(startIndex,
						totalCount,
						pageSize,
						this.queryPagedResult(hql, startIndex, pageSize, parameters));
	}

	/**
	 * 原生sql分页查询,不带参数
	 *
	 * @param sql
	 * @param currentPage
	 * @param pageSize
	 * @return
	 */
	public Page pagedSqlQueryByPageNo(String sql,
									  int currentPage,
									  int pageSize) {
		return this.pagedSqlQueryByPageNo(sql,currentPage,pageSize,null);
	}

     /**
	 * 原生sql分页查询
	 * @param sql
	 * @param currentPage
	 * @param pageSize
	 * @param parameters
	 * @return
	 */
	public Page pagedSqlQueryByPageNo(String sql,
									  int currentPage,
					  				  int pageSize,
									  Object[] parameters){

		Long totalCount =  ((BigInteger)this.createSQLQuery(buildCountQueryStr(sql), parameters).uniqueResult()).longValue(); //获取总行数

		if (totalCount < 1) {
			return new Page();
		}
		int startIndex = getFirstRow(currentPage, pageSize);//获取开始行
		//构建page对象
		return new Page(startIndex,
						totalCount,
						pageSize,
						this.sqlQueryPagedResult(sql,startIndex,pageSize,parameters));
	}

	/**
	 * 功能描述: 分页查询，支持SQL语句命名参数的查询
	 * @param hql: 查询语句
	 * @param currentPage : 当前页码
	 * @param pagesize： 每页的记录数
	 * @param parameters ： 命名参数的键值
	 * Edit author: 罗军林
	 * Edit on: 2008-12-23
	 *
	 * @return 分页对象
	 */
	public Page pagedSqlNameQueryByPageNo(String sql,
									   int currentPage,
									   int pageSize,
									   Map parameter) {
	    long totalCount = ((BigInteger)this.createNameSQLQuery(buildCountQueryStr(sql), parameter).uniqueResult()).longValue();
	    if (totalCount < 1) {
	    	return new Page();
	    }

		int startIndex = getFirstRow(currentPage, pageSize);//获取开始行

		// 构建page对象
		return new Page(startIndex,
						totalCount,
						pageSize,
						this.createNameSQLQuery(sql, parameter)
						.setFirstResult(startIndex)
						.setMaxResults(pageSize)
						.list());
	}

	/**
	 * 功能描述： 返回当前页的记录数组
	 *
	 *
	 */
	public List queryNamePagedResult(String queryStr,
									 int firstRow,
									 int pageSize,
									 Map parameter) {
		return this.createNameQuery(queryStr, parameter).setFirstResult(firstRow)
											.setMaxResults(pageSize).list();
	}

	/**
	 * Function:根据Criteria查询实体列表
	 * @param Criteria
	 * @return List<D>
	 * Create author:付湘辉
	 * Create on:2008-5-12
	 * Edit author:燕大为
	 * Edit on:2008-5-21
	 * Why:
	 */
	public List<D> queryObjects(Criteria criteria) {
		List<D> list =  this.pmsBaseHibernateDao.queryObjectInBase(criteria);
		return list;
	}

	/**
	 * 功能描述： 返回当前页的记录数组
	 *
	 *
	 */
	public List queryPagedResult(String queryStr,
								 int firstRow,
								 int pageSize,
								 Object... values) {
		return this.createQuery(queryStr, values).setFirstResult(firstRow)
											.setMaxResults(pageSize).list();
	}

	/**
	 * Function:添加实体
	 * @param
	 * @return
	 * Create author:daibiao
	 * Create on:2008-1-28
	 * Edit author:燕大为
	 * Edit on: 2008-5-21
	 * Why: 方便数据拦截
	 */
	public D saveObject(D d) {
//		try {
//			getHibernateTemplate().save(d);
			this.doSave(d);
			return d;
//		} catch (DataAccessException e) {
//			throw new DataAccessLayerException("pms.base.001");
//		}
	}

	 /**
	 * Function:添加或修改实体
	 * @param D DO对象
	 * @return DO对象
	 * Create author:huxu
	 * Create on:2008-4-15
	 * Edit author:燕大为
	 * Edit on: 2008-5-21
	 * Why: 方便数据拦截
	 * Why:UI需求
	 */
	public D saveOrUpdateObject(D d){
		//getHibernateTemplate().saveOrUpdate(d);
		this.doSave(d);
		return d;
	}

    public void setPmsBaseHibernateDao(IPmsBaseHibernateDao pmsBaseHibernateDao) {
		this.pmsBaseHibernateDao = pmsBaseHibernateDao;
	}

    public void setSysrefcodeDao(ISysrefcodeDao sysrefcodeDao) {
		this.sysrefcodeDao = sysrefcodeDao;
	}

	 /**
	 * 原生sql查询某一页
	 * @param queryStr
	 * @param firstRow
	 * @param pageSize
	 * @param values
	 * @return
	 */
	public List sqlQueryPagedResult(String queryStr,
									int firstRow,
									int pageSize,
									Object... values) {
		return this.createSQLQuery(queryStr, values).setFirstResult(firstRow)
						.setMaxResults(pageSize).list();
	}

	/**
	 * Function:修改实体
	 * @param
	 * @return
	 * Create author:daibiao
	 * Create on:2008-1-28
	 * Edit author:燕大为
	 * Edit on: 2008-5-21
	 * Why: 方便数据拦截
	 */
	public D updateObject(D d) {
//		try {
//			getHibernateTemplate().update(d);
			this.doSave(d);
			return d;
//		} catch (DataAccessException e) {
//			throw new DataAccessLayerException("pms.base.001");
//		}
	}



	public void executeSQLBatch(String sql, List<Object[]> parameters) {
		pmsBaseHibernateDao.executeSQLBatch(sql, parameters);

	}

	/**
	 * Function:在查询列表时，需要获取总页数
	 * @param hql
	 * @param paramenter 命名参数的键值
	 * @param flag为ture 则表示HQL查询，否则为原生SQL查询
	 *
	 * @return
	 * Create author:易贤建
	 * Create on:2008-3-12
	 * Edit author:罗军林
	 * Edit on: 2008-8-12
	 * Why: 增加对命名参数的支持
	 */
	private long getTotalCount(String hql,Map paramenter,boolean isHql){
		if(isHql){
			return (Long) this.createNameQuery(buildCountQueryHQLStr(hql), paramenter).uniqueResult();
		}

		return (Long) this.createNameQuery(buildCountQueryStr(hql), paramenter).uniqueResult();
	}

	/**
	 * Function:在查询列表时，需要获取总页数
	 * @param flag为ture 则表示HQL查询，否则为原生SQL查询
	 * @return
	 * Create author:易贤建
	 * Create on:2008-3-12
	 * Edit author:
	 * Edit on:
	 * Why:
	 */
	private long getTotalCount(String hql,Object[] paramenters,boolean isHql){
		if(isHql){
			return (Long) this.createQuery(buildCountQueryHQLStr(hql), paramenters).uniqueResult();
		}

		return (Long) this.createQuery(buildCountQueryStr(hql), paramenters).uniqueResult();
	}
	public void clear() {
		this.pmsBaseHibernateDao.clear();

	}
	public void flush() {
		this.pmsBaseHibernateDao.flush();

	}

	/**
	 * 功能描述:加载指定标识的对象<br>
	 * @param entiyClass
	 * @param id
	 * @return<br>
	 * Create author:罗军林<br>
	 * Create on:2008-12-8<br>
	 * Edit author:<br>
	 * Edit on:<br>
	 * Why:<br>
	 */
	public D loadById(Serializable id){
		return (D)pmsBaseHibernateDao.loadById(this.entityClass, id);
	}

	/**
	 *
	 */
	private static final String DEFAULT_NAME_KEY = "name";
	/**
	 *
	 */
	private String nameKey = DEFAULT_NAME_KEY;
	/**
	 *
	 */
	private String classSimpleName ;

	/**
	 * 方法描述: 根据名称查找唯一对象。
	 * 使用条件：“名称”是记录集合中唯一。如果“名称”字段不是“name”，那么请先使用setNameKey(String name)改变字段属性
	 * @author: 王浩羽
	 * Create on: Dec 22, 2008
	 * @param name 对象的“名称”值
	 * @return
	 * Edit author:
	 * Edit on:
	 * 修改原因:
	 */
	public D findUniqueByName(String name)
	{
//		return (D)this.findUnique(this.crtieriaFindBy(nameKey, name));
		if(!StringUtils.hasText(classSimpleName))
		{
			getClassSimpleName();
		}
		StringBuilder hqlBuilder = new StringBuilder();
		hqlBuilder.append("SELECT OBJ FROM ").append(classSimpleName).append(" OBJ where OBJ.").append(nameKey).append("= ? ");
		List<D> list = createQuery(hqlBuilder.toString(), name).list();
		if(list==null || list.isEmpty())
		{
			return null;
		}
		return list.get(0);
	}

	/**
	 * 方法描述: 获取泛型类型
	 * @author: 王浩羽
	 * Create on: Dec 22, 2008
	 * @return
	 * Edit author:
	 * Edit on:
	 * 修改原因:
	 */
	public Class<D> getClassType()
	{
		 return (Class<D>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
	}

	/**
	 * 方法描述: 获取泛型类型的简单名称
	 * @author: 王浩羽
	 * Create on: Dec 22, 2008
	 * @return
	 * Edit author:
	 * Edit on:
	 * 修改原因:
	 */
	public String getClassSimpleName()
	{
		if(! StringUtils.hasText(classSimpleName))
		{
			classSimpleName = getClassType().getSimpleName();
		}
		 return classSimpleName;
	}

	/**
	 * 方法描述: 按页查询，page中的list所含的类型未做转换
	 * @author: 王浩羽
	 * Create on: Dec 22, 2008
	 * @param searchVO
	 * @return
	 * Edit author:
	 * Edit on:
	 * 修改原因:
	 */
	public Page queryByPage(SearchVO searchVO)
	{
		if(!StringUtils.hasText(classSimpleName))
		{
			getClassSimpleName();
		}
		StringBuilder hqlBuilder = new StringBuilder();
		hqlBuilder.append("SELECT OBJ FROM ").append(classSimpleName).append(" OBJ where 1=1 ");
		if(!BlankUtil.isBlank(searchVO.getOrderKey()) && !BlankUtil.isBlank(searchVO.getOrderValue()))
		{
			hqlBuilder.append(" ORDER BY ").append("OBJ.").append(searchVO.getOrderValue()).append(" ").append(searchVO.getOrderKey());
		}
		return this.pagedQueryByPageNo(hqlBuilder.toString(), searchVO.getPageNo(), searchVO.getPageSize());
	}

	/**
	 * 方法描述: 设置对象的“名称”字段key
	 * 使用前提：如果对象的“名称”字段不是默认值“name”
	 * @author: 王浩羽
	 * Create on: Dec 22, 2008
	 * @param nameKey
	 * Edit author:
	 * Edit on:
	 * 修改原因:
	 */
	protected void setNameKey(String nameKey)
	{
		this.nameKey = nameKey;
	}
}
